//#include "VBLib/VBLib.h"
#include <cstdlib> // atoi
#include <typeinfo>
#include <iostream>
#include <tau_defines.h>

template <typename T, unsigned size>
class Tauint {
private:
    T m_data[size];

    enum {
        byte = 8, //bits of a byte
        count_size = size - 1, //index of the last T of the array
        sub_int_size = (sizeof (T)), //Number of bytes of the type T which will compound the hole Tau_int
        sub_int_bit_size = sub_int_size*byte, //Number of bits of the type T which will compound the hole Tau_int
        sub_int_bit_count = sub_int_bit_size - 1, //Number of bits of the type T which will compound the hole Tau_int
        bit_size = size*sub_int_bit_size, //Number of bits of Tau_int
        count_bit_size = bit_size - 1, //Indez of the last bit of the array
        sub_int_count = sub_int_size - 1, //Number of bits of the type T which will compound the hole Tau_int
        Tau_int_bit = size*sub_int_size, //Total Number of bits of the Tau_int, that is equal the number of bits of each T, times the number of T's
        //~ last_bit = (1 << (sizeof (T))),		//Bit mask that has a 1 at the very last bit of T
        //~ before_last_bit = ~last_bit			//Bit mask that has a 1 at the very last bit of T
        max_base = 36, //Max base allowed is 36 (= 26 letters of alphabet + 10 indo-arabic algarisms)
        bin = 2, //Bases
        dec = 10,
    }; //Remember to add here a bitwise mask of all 1 except on the sizeof bitamount-th bit this will take off the need of the loop on j. There will be only 2 sums on each block of the loop on i.

public:
    //Class' static useful constants begin:

    inline static T m_allBit() {
        return ~0;
    } //These avoid the 'dangerous' use of static variables.

    inline static T m_lastBit() {
        return 1 << sub_int_bit_count;
    } //

    static Tauint MinusOne() {
        Tauint ret;
        for (int i = 0; i < size; i++) {
            ret.m_data[i] = ~0;
        }
        return ret;
    }

    int getOrder () {
        //FUN_LOG(1,int getOrder ())
        T mask(m_lastBit());
        for (int i = count_size; i >= 0; i--) {
            //YSVB_SHOW(i)
            //FUN_LOG(1,for (int i = count_size; i >= 0; i--))
            if (m_data[i]) {//asm...
                for (int j = sub_int_bit_count; j >= 0; j--, mask /= 2) {
                    //YSVB_SHOW(j)
                    //FUN_LOG(1,for (int j = sub_int_bit_count; j >= 0; j--, mask /= 2))
                    if (m_data[i] & mask) {
                        YSVB_ASSERT_PLUS(mask,>=,0)
                        if (j == 0) {
                            YSVB_ASSERT_PLUS(mask,==,1)
                        }
                        return i*sub_int_bit_size + j;
                    }
                }
            }
        }
        YSVB_ASSERT_PLUS(*this,==,Zero())
        return -1;
    }
    
    static Tauint Zero() {
        Tauint ret;
        for (int i = 0; i < size; i++) {
            ret.m_data[i] = 0;
        }
        return ret;
    }

    static Tauint One() {
        Tauint ret;
        ret.m_data[0] = 1;
        YSVB_ASSERT_PLUS(ret.m_data[0], ==, 1)
        for (int i = 1; i < size; i++) {
            ret.m_data[i] = 0;
            YSVB_ASSERT_PLUS(ret.m_data[i], ==, 0)
        }
        YSVB_ASSERT_PLUS(ret, >, Zero())
        YSVB_ASSERT_PLUS(ret, <, (MinusOne() + MinusOne()).minus())
        return ret;
    }

    static Tauint Two() {
        Tauint ret;
        ret.m_data[0] = 2;
        YSVB_ASSERT_PLUS(ret.m_data[0], ==, 2)
        for (int i = 1; i < size; i++) {
            ret.m_data[i] = 0;
            YSVB_ASSERT_PLUS(ret.m_data[i], ==, 0)
        }
        YSVB_ASSERT_PLUS(ret, >, One())
        YSVB_ASSERT_PLUS(ret, <, One() + One() + One())
        return ret;
    }

    static Tauint Ten() {
        Tauint ret;
        ret.m_data[0] = 10;
        for (int i = 1; i < size; i++) {
            ret.m_data[i] = 0;
        }
        return ret;
    }

    static Tauint binaryStringToTau(const std::string & str) {
        //std::cout << "static Tauint binaryStringToTau(const std::string & str)" << std::endl;
        Tauint ret;
        ret.setBinaryDataFromString(str.c_str());
        YSVB_ASSERT_PLUS(ret.getBinaryDataString(),==,str)
        return ret;
    }

    static Tauint unitToTau(T unit) {
        Tauint ret;
        if (unit > 0) {
            ret.m_data[0] = unit;
            for (int i = 1; i < size; i++) {
                ret.m_data[i] = 0;
            }
        } else {
            ret.m_data[0] = (unit & ~(Tauint::m_lastBit()));
            for (int i = 1; i < size; i++) {
                ret.m_data[i] = 0;
            }
            ret = ret.minus();
        }
        return ret;
    }

    inline T firstUnit() {
        //std::cout << "inline T firstUnit() " << std::endl;
        return m_data[0];
    }
    //Class' static useful constants and methods end.

    inline T operator[] (unsigned i) const {
        return m_data[i];
    }

    inline T & operator() (unsigned i) {
        return m_data[i];
    }

public:

    Tauint unsigned_atoi(const std::string & str) {
        using namespace std;
        //std::cout << "Tauint unsigned_atoi(const std::string & str)" << std::endl;
        Tauint ret(Zero());
        YSVB_ASSERT_PLUS(ret.getBinaryDataString(), ==, "0")
                const Tauint factor(Ten());
        YSVB_ASSERT_PLUS(factor.getBinaryDataString(), ==, "1010")
        Tauint power(One());
        YSVB_ASSERT_PLUS(power.getBinaryDataString(), ==, "1")
        Tauint parcel(Zero());
        YSVB_ASSERT_PLUS(parcel.getBinaryDataString(), ==, "0")
        Tauint holder(Zero());
        YSVB_ASSERT_PLUS(holder.getBinaryDataString(), ==, "0")
                int i;
        const int N = str.size();
        YSVB_ASSERT_PLUS(N, >=, 1)
                bool good = true;
        YSVB_ASSERT_PLUS(good, ==, true)
        for (i = 0; i < N && good; i++) {
            good = good && str[i] >= '0';
            good = good && str[i] <= '9';
        }
        if (good) {
            YSVB_ASSERT_PLUS(good, ==, true)
            for (i = N - 1; i >= 0; i--, power = power * factor) {
                holder = (unitToTau((T) atoi((str.substr(i, 1)).c_str())));
                parcel = (holder * power);
                YSVB_ASSERT_PLUS((atoi((str.substr(i, 1)).c_str())), >=, 0)
                YSVB_ASSERT_PLUS((atoi((str.substr(i, 1)).c_str())), <=, 9)
                YSVB_ASSERT_PLUS(ret, <=, ret + parcel)
                ret = ret + parcel;
            }
            return ret;
        } else {
            //Error Handler here.
            ret = Tauint(Zero());
            YSVB_ASSERT_PLUS(ret.getBinaryDataString(), ==, "0")
            return ret;
        }
    }

public:

    void setData(const Tauint & target) {
        for (int i = 0; i < size; i++) {
            m_data[i] = target[i];
        }
    }

    void setDecimalDataFromString(const std::string & str) {
        //std::cout << "void setDecimalDataFromString(const std::string & str)" << std::endl;
        Tauint holder(Zero());
        YSVB_ASSERT_PLUS(holder.getBinaryDataString(), ==, "0")
        if (str[0] == '-') {
            holder = (unsigned_atoi((str.substr(1, str.size() - 1)).c_str()));
            YSVB_ASSERT_PLUS(holder, >, Tauint(Zero()))
            holder = holder.minus();
            YSVB_ASSERT_PLUS(holder, <, Tauint(Zero()))
            setData(holder);
            YSVB_ASSERT_PLUS((*this), <, Tauint(Zero()))
        } else {
            if (str[0] == '+') {
                holder = (unsigned_atoi((str.substr(1, str.size() - 1)).c_str()));
                YSVB_ASSERT_PLUS(holder, >, Tauint(Zero()))
                setData(holder);
                YSVB_ASSERT_PLUS((*this), >, Tauint(Zero()))
            } else {
                holder = (unsigned_atoi((str).c_str()));
                YSVB_ASSERT_PLUS(holder, >, Tauint(Zero()))
                setData(holder);
                YSVB_ASSERT_PLUS((*this), >, Tauint(Zero()))
            }
        }
    }

    std::string unsigned_itoa() const {
        //std::cout << "std::string unsigned_itoa() const " << std::endl;
        YSVB_ASSERT_PLUS(get_sign(), ==, false)
        Tauint helper;
        std::string ret;
        char holder;
        for (helper = (*this); helper > Zero(); helper = helper / Ten()) {
            //std::cout << "It is an iteration." << std::endl;
            YSVB_ASSERT_PLUS((bool) helper.get_sign(), ==, false)
            YSVB_ASSERT_PLUS((helper % Ten()) + unitToTau((T) '0'), >=, unitToTau((T)'0'))
            YSVB_ASSERT_PLUS((helper % Ten()) + unitToTau((T) '0'), <=, unitToTau((T)'9'))
            holder = (((char) (helper % Ten()).firstUnit())+'0');
            ret = holder + ret;
        }
        if (ret == "")  {
            ret = "0";
        }
        YSVB_ASSERT_PLUS(ret,!=,"")
        return ret;
    }

    std::string getDecimalString() const {
        //std::cout << "std::string getDecimalString() const" << std::endl;
        std::string ret;
        if (get_sign()) {
            ret = "-" + (minus()).unsigned_itoa();
            YSVB_ASSERT_PLUS((int) ret[0], ==, (int) '-')
            YSVB_ASSERT_PLUS((int) ret[1], >=, (int) '1')
            YSVB_ASSERT_PLUS((int) ret[1], <=, (int) '9')
        } else {
            ret = unsigned_itoa();
            if (*this == Zero()) {
                YSVB_ASSERT_PLUS(ret,==,"0")
            } else {
                YSVB_ASSERT_PLUS((int) ret[0], >=,(int) '1')
                YSVB_ASSERT_PLUS((int) ret[0], <=,(int) '9')
            }
        }
        return ret;
    }

    Tauint() {
    }

    inline unsigned getSize() const {
        return size;
    }

    inline std::string getType() const {
        return typeid (T).name();
    }

    void set_data_0() {
        for (int i = 0; i < size; i++) {
            //            YSVB_SHOW(i)
            this->m_data[i] = 0;
            //            YSVB_SHOW(this->m_data[i])
        }
        //        YSVB_SHOW(this->getBinaryDataString())
    }

    void setBinaryDataFromString(const char* str) {
        set_data_0();
        int i, j, Ns, Ni, Nj;
        T mask;
        bool good;
        for (Ns = 0, good = true; str[Ns] != 0 && good; Ns++) {
            if (str[Ns] != '0' && str[Ns] != '1') {
                good = false;
            }
        }
        if (good) {
            if (str != "0") {
                //                            YSVB_SHOW(Ns)
                Nj = Ns % sub_int_bit_size;
                Ni = Ns / sub_int_bit_size;
                //                            YSVB_SHOW(Ni)
                //                            YSVB_SHOW(Nj)
                for (i = 0; i < Ni; i++) {
                    for (j = 0, mask = 1; j < sub_int_bit_size; j++, mask *= 2) {
                        //                    YSVB_SHOW(i)
                        //                    YSVB_SHOW(j)
                        //                    YSVB_SHOW(Ns-(i*sub_int_bit_size+j)-1)
                        //                    YSVB_SHOW((int) mask)
                        if (str[Ns - (i * sub_int_bit_size + j) - 1] == '1') {
                            //                        YSVB_SHOW(Ns-(i*sub_int_bit_size+j))
                            //                        //                        YSVB_SHOW(i)
                            //                        //                        YSVB_SHOW(j)
                            //                        YSVB_SHOW(str)this->
                            //                                                    YSVB_SHOW((int) m_data[i])
                            m_data[i] = m_data[i] | mask;
                            //                                                    YSVB_SHOW((int) m_data[i])
                        }
                    }
                }
                for (j = 0, mask = 1; j < Nj; j++, mask *= 2) {
                    //                                    YSVB_SHOW(i)
                    //                                    YSVB_SHOW(j)
                    //                                    YSVB_SHOW(Ns-(i*sub_int_bit_size+j)-1)
                    //                                    YSVB_SHOW((int) mask)
                    if (str[Ns - (i * sub_int_bit_size + j) - 1] == '1') {
                        //                    YSVB_SHOW(i)
                        //                    YSVB_SHOW(j)
                        //                    YSVB_SHOW(str)
                        //                                            YSVB_SHOW((int) m_data[i])
                        m_data[i] = m_data[i] | mask;
                        //                                            YSVB_SHOW((int) m_data[i])
                        //                        YSVB_SHOW(getBinaryDataString())
                    }
                }
            } else {
                YSVB_ASSERT_PLUS(getBinaryDataString(), ==, "0")
            }
        } else {
            std::cout << "Error: Binary input data is not binary." << std::endl;
        }
        //        YSVB_SHOW(getBinaryDataString())
    }

    std::string getBinaryDataString() const {
        //        YSVB_SHOW("std::string getBinaryDataString() const CALLED")
        int i(0), j(0), Ni(0), Nj(0);
        T mask;
        for (i = 0; i < size; i++) {
            for (j = 0, mask = 1; j < sub_int_bit_size; j++) {
                //                YSVB_SHOW((int) (m_data[i]))
                //                YSVB_SHOW((int) (mask))
                if (m_data[i] & mask) {
                    //                    YSVB_SHOW((int) (m_data[i] & mask))
                    //                    YSVB_SHOW(i)
                    //                    YSVB_SHOW(j)
                    Ni = (i * sub_int_bit_size) + j;
                }
                mask *= 2;
            }
        }
        //YSVB_SHOW(Ni)
        Nj = Ni % sub_int_bit_size;
        Ni /= sub_int_bit_size;
        if (Ni || Nj || m_data[0]) {
            YSVB_ASSERT_PLUS((Ni == 0 && Nj == 0 && m_data[0] == 0), ==, false)
            std::string ret;
            //YSVB_SHOW(Ni)
            //YSVB_SHOW(Nj)
            //YSVB_SHOW(m_data[0])
            for (i = 0; i < Ni; i++) {
                for (j = 0, mask = 1; j < sub_int_bit_size; j++, mask *= 2) {
                    ret = ((m_data[i] & mask) ? ('1') : ('0')) + ret;
                }
            }
            for (j = 0, mask = 1; j <= Nj; j++, mask *= 2) {
                //VB_SHOW(ret)
                //VB_SHOW(m_data[i])
                //VB_SHOW(mask)
                ret = ((m_data[i] & mask) ? ('1') : ('0')) + ret;
                //VB_SHOW(ret)
            }
            return ret;
        } else {
            YSVB_ASSERT_PLUS((Ni == 0 && Nj == 0 && m_data[0] == 0), ==, true)
            return "0";
        }
    }

    friend std::ostream & operator <<(std::ostream & s, const Tauint & target) {
        s << target.getBinaryDataString(); // s.operator<<(z.m_i);
        return s;
    }

private:

    Tauint SUM_P(const Tauint & target) const {
        //        YSVB_SHOW("SUM_P(const Tauint & target) const CALLED")
        T g1, sub_data; //goes one and variable that hold the parcel
        int i; //
        Tauint ret;
        //        YSVB_SHOW(ret.getBinaryDataString())
        for (i = 0, g1 = 0; i < count_size; i++) {
            sub_data = (target.m_data[i] + g1);
            g1 = (~target.m_data[i] || !g1) ? 0 : 1;
            ret.m_data[i] = sub_data + m_data[i];
            //            YSVB_SHOW(ret.getBinaryDataString())
            g1 = (g1) ? (1) : (((ret.m_data[i] < sub_data) && (ret.m_data[i] < sub_data)) ? (1) : (0));
        }
        ret.m_data[i] = m_data[i] + target.m_data[i] + g1;
        //        YSVB_SHOW(ret.getBinaryDataString())
        return ret;
    }

    Tauint operator~() const {
        Tauint ret;
        for (int i = 0; i < size; i++) {
            ret.m_data[i] = ~(this->m_data[i]);
        }
        return ret;
    }

    Tauint minus() const {
        Tauint ret(~(SUM_P(MinusOne())));
        return ret;
    }

    Tauint SUM_N(const Tauint & target) const {
        //        YSVB_SHOW("SUM_N CALLED")
        Tauint holder(target.minus());
        //        YSVB_SHOW(holder.getBinaryDataString())
        //        YSVB_SHOW(this->getBinaryDataString())
        //        //YSVB_SHOW(linha++)
        return SUM_P(holder);
    }

    Tauint SUM(bool sign, const Tauint & target) const {
        return ((sign) ? (SUM_N(target)) : (SUM_P(target)));
    }

    bool operator<(const Tauint & target) const {
        //std::cout << "bool operator<(const Tauint & target) const" << std::endl;
        if (get_sign()) {
            if (target.get_sign()) {
                return (minus() > target.minus());
            } else {
                return true;
            }
        } else {
            if (target.get_sign()) {
                return false;
            } else {
                int i, j;
                //T mask;
                for (i = count_size; i >= 0; i--) {
                    if (target.m_data[i] - m_data[i]) {
                        return m_data[i] < target.m_data[i];
                    }
                }
                return false;
            }
        }
    }

    inline bool operator>(const Tauint & target) const {
        return target < *this;
    }

    inline bool operator <=(const Tauint & target) const {
        return !(*this > target);
    }

    inline bool operator >=(const Tauint & target) const {
        return !(*this < target);
    }

    bool operator ==(const Tauint & target) const {
        for (int i = 0; i < size; i++) {
            if (m_data[i] != target[i]) {
                return false;
            }
        }
        YSVB_ASSERT_PLUS((*this), <=, target)
        YSVB_ASSERT_PLUS((*this), >=, target)
        return true;
    }

    inline bool operator !=(const Tauint & target) const {
        return !(*this == target);
    }

    Tauint MULT_P_0_SUM_iteration(const Tauint & target) const {
        FUN_LOG(0,MULT_P_0_SUM_iteration(const Tauint & target) const)
        YSVB_ASSERT_PLUS(*this, >=, Zero())
        YSVB_ASSERT_PLUS(target, >=, Zero())
        Tauint ret(Zero());
        Tauint i;
//        YSVB_SHOW(*this)
//        YSVB_SHOW(target)
        for (i = Tauint(Zero()); i < target; i = i + One()) {//IMPLEMENT ++
            FUN_LOG(0,for (i = Tauint(Zero()); i < target; i = i + One()))
            //YSVB_ASSERT_PLUS(i,>=,target)
            //FUN_LOG(i < target,i)
            ret = ret + (*this);
        }
        return ret;
    }

    Tauint MULT_P_1_shift(const Tauint & target) const {
        FUN_LOG(0,Tauint MULT_P_1_shift(const Tauint & target) const)
        YSVB_ASSERT_PLUS(*this, >=, Zero())
        YSVB_ASSERT_PLUS(target, >=, Zero())
        YSVB_ASSERT_PLUS((this->m_data[count_size]&Tauint::m_lastBit()),==,0)
        YSVB_ASSERT_PLUS((target[count_size]&Tauint::m_lastBit()),==,0)
        Tauint ret(Zero());
        Tauint parcel;
        T mask;
        int i, j;//Loop Handlers
//        YSVB_SHOW(*this)
//        YSVB_SHOW(target)
        for (i = 0; i < size; i++) {
            FUN_LOG(0,for (i = 0; i < size; i++))
            for (j = 0, mask = (T) 1; j < sub_int_bit_size; j++, mask *= 2) {
                FUN_LOG(0,for (j = 0, mask = (T) 1; j < sub_int_bit_size; j++, T *= 2))
                YSVB_ASSERT_PLUS(mask,>,0)
                if (target[i]&mask) {
                    parcel = (*this) << j;
                    ret = ret + parcel;
                    YSVB_ASSERT_PLUS(ret,>=,Zero())//This must be removed!
                }
            }
        }
        YSVB_ASSERT_PLUS(ret,>=,Zero())
        return ret;
    }

    Tauint operator << (unsigned shift) const {
        FUN_LOG(0,operator << (unsigned shift) const)
        Tauint ret(Zero());
        const unsigned  block(shift/sub_int_bit_size), 
                        //comp_block(size-block),
                        inner(shift%sub_int_bit_size),
                        comp_inner(sub_int_bit_size-inner);
        int iR(0), jR, iW(block), jW;//loop handlers
        T Rmask, Wmask;
        YSVB_ASSERT_PLUS(ret.getBinaryDataString(),==,"0");


#ifdef LOGIC_TEST
        for (jR = 0, jW = inner, Rmask = (T) 1, Wmask = (1<<inner);
                jR < comp_inner/*, jW < sub_int_bit_size*/;
                jR++, jW++, Rmask *= 2, Wmask *= 2)
#else
        for (jR = 0/*, jW = inner,*/ Rmask = (T) 1, Wmask = (1<<inner);
                jR < comp_inner/*, jW < sub_int_bit_size*/;
                jR++/*, jW++*/, Rmask *= 2, Wmask *= 2)
#endif
        {
            YSVB_ASSERT_PLUS(jW,<,sub_int_bit_size)
            YSVB_ASSERT_PLUS(sub_int_bit_size-jW,==,comp_inner-jR)
            YSVB_ASSERT_PLUS(iR,==,0)
            if ((m_data[iR]&Rmask) != 0) {//set jth bit of ret(i) to 1
                //YSVB_ASSERT_PLUS(((bool) m_data[iR]&Rmask),==,true)//This strangely doesn't work for T = short int
                YSVB_ASSERT_PLUS((m_data[iR]&Rmask),!=,0)
                ret(iW) = ret(iW) | Wmask;
            }
        }
        //YSVB_ASSERT_PLUS(ret.getBinaryDataString(),==,"0")
        YSVB_ASSERT_PLUS(iW,<,size)
        YSVB_ASSERT_PLUS(iW,==,0)

                
        for (iW++; iW < size; iW++) {
            YSVB_ASSERT_PLUS(Rmask,==,((comp_inner==sub_int_bit_size)?(0):((T) 1 << comp_inner)))
            YSVB_ASSERT_PLUS(Wmask,==,0)//At this point, all bits were swapped
#ifdef LOGIC_TEST
            for (jW = 0, Wmask = (1), Rmask = (Rmask)?(Rmask):(1);
                    jW < inner;
                    jR++, jW++, Rmask *= 2, Wmask *= 2)
#else
            for (jW = 0, Wmask = (1), Rmask = (Rmask)?(Rmask):(1);
                    jW < inner;
                    jR++, jW++, Rmask *= 2, Wmask *= 2)
#endif
            {
                YSVB_ASSERT_PLUS(inner,>=,0)
                YSVB_ASSERT_PLUS(jR,<,sub_int_bit_size)
                YSVB_ASSERT_PLUS(sub_int_bit_size-jR,==,inner-jW)
                YSVB_ASSERT_PLUS(Rmask,!=,0)
                if ((m_data[iR]&Rmask) != 0) {//set jth bit of ret(i) to 1
                    //YSVB_ASSERT_PLUS(((bool) m_data[iR]&Rmask),==,true)//This strangely doesn't work for T = short int
                    YSVB_ASSERT_PLUS((m_data[iR]&Rmask),!=,0)
                    ret(iW) = ret(iW) | Wmask;
                }
            }
            YSVB_ASSERT_PLUS(Rmask,==,0)
            YSVB_ASSERT_PLUS(jW,==,inner)
            YSVB_ASSERT_PLUS(Wmask,==,(1 << inner))



#ifdef LOGIC_TEST
            for (iR++, jR = 0/*, jW = inner*/, Rmask = (T) 1/*, Wmask = (1<<inner)*/;
                    jR < comp_inner/*, jW < sub_int_bit_size*/;
                    jR++, jW++, Rmask *= 2, Wmask *= 2)
#else
            for (iR++, jR = 0/*, jW = inner,*/ Rmask = (T) 1/*, Wmask = (1<<inner)*/;
                    jR < comp_inner/*, jW < sub_int_bit_size*/;
                    jR++/*, jW++*/, Rmask *= 2, Wmask *= 2)
#endif            
            {
                YSVB_ASSERT_PLUS(jW,<,sub_int_bit_size)
                YSVB_ASSERT_PLUS(sub_int_bit_size-jW,==,comp_inner-jR)
                YSVB_ASSERT_PLUS(comp_inner,<=,sub_int_bit_size)
                if ((m_data[iR]&Rmask) != 0) {//set jth bit of ret(i) to 1
                    //YSVB_ASSERT_PLUS(((bool) m_data[iR]&Rmask),==,true)//This strangely doesn't work for T = short int
                    YSVB_ASSERT_PLUS((m_data[iR]&Rmask),!=,0)
                    ret(iW) = ret(iW) | Wmask;
                }
            }
            YSVB_ASSERT_PLUS(Rmask,==,((comp_inner==sub_int_bit_size)?(0):((T) 1 << comp_inner)))
            YSVB_ASSERT_PLUS(Wmask,==,0)
        }
        return ret;
    }

    public:

    inline bool get_sign() const {
        return m_data[count_size] & m_lastBit();
    }

    Tauint inline operator +(const Tauint & target) const {
        return (SUM(false, target));
    }

    Tauint inline operator -(const Tauint & target) const {
        return (SUM(true, target));
    }

    Tauint operator *(const Tauint & target) const {
        FUN_LOG(0,operator *(const Tauint & target) const)
        if (get_sign()) {
            if (target.get_sign()) {
                YSVB_ASSERT_PLUS(*this, <, Zero())
                YSVB_ASSERT_PLUS(target, <, Zero())
                return ((minus()).MULT_P_1_shift(target.minus()));
            } else {
                YSVB_ASSERT_PLUS(*this, <, Zero())
                YSVB_ASSERT_PLUS(target, >, Zero())
                return (((minus()).MULT_P_1_shift(target)).minus());
            }
        } else {
            if (target.get_sign()) {
                YSVB_ASSERT_PLUS(*this, >, Zero())
                YSVB_ASSERT_PLUS(target, <, Zero())
                return (((minus()).MULT_P_1_shift(target.minus())).minus());
            } else {
                //std::cout << "== Tauint operator *(const Tauint & target) const " << std::endl;
                YSVB_ASSERT_PLUS(*this, >=, Zero())
                YSVB_ASSERT_PLUS(target, >=, Zero())
                return ((minus()).MULT_P_1_shift(target));
            }
        }
    }

    Tauint DIV_P_0(const Tauint & target, bool QorR) const {//Euclidean Algorithm
        //std::cout << "DIV_P_0 (const Tauint & target, bool QorR) const " << std::endl;
        YSVB_ASSERT_PLUS(target, !=, Zero())
        Tauint helper, quocient;
        for (quocient = Zero(), helper = (*this);
            helper > Zero();
            quocient = quocient + One()) {//IMPLEMENT ++
            helper = helper - target;
        }
        if (QorR) {
            if (helper>=Zero()) {
                YSVB_ASSERT_PLUS(helper,==,Zero())
                YSVB_ASSERT_PLUS(quocient, <=, *this)
                YSVB_ASSERT_PLUS(quocient, >=, Zero())
                return quocient;
            } else {
                quocient = (quocient - One());
                YSVB_ASSERT_PLUS(quocient, <=, *this)
                YSVB_ASSERT_PLUS(quocient, >=, Zero())
                return quocient;
            }
        } else {
            if (helper>=Zero()) {
                YSVB_ASSERT_PLUS((helper), <, target)
                YSVB_ASSERT_PLUS((helper), >=, Zero())
                return helper;
            } else {
                helper = helper + target;
                YSVB_ASSERT_PLUS((helper), <, target)
                YSVB_ASSERT_PLUS((helper), >=, Zero())
                return helper;
            }
        }
    }

    Tauint operator /(const Tauint & target) const {
        //std::cout << "== Tauint operator /(const Tauint & target) const " << std::endl;
        Tauint ret;
        if (target == Zero()) {
            std::cout << "Fatal Error: Division for 0" << std::endl;
            return Zero();
        } else {
            if (get_sign()) {
                if (target.get_sign()) {
                    ret = ((minus()).DIV_P_0(target.minus(),true));
                    YSVB_ASSERT_PLUS(*this, <, Zero())
                    YSVB_ASSERT_PLUS(target, <, Zero())
                    return ((minus()).DIV_P_0(target.minus(),true));
                } else {
                    YSVB_ASSERT_PLUS(*this, <, Zero())
                    YSVB_ASSERT_PLUS(target, >, Zero())
                    return (((minus()).DIV_P_0(target,true)).minus());
                }
            } else {
                if (target.get_sign()) {
                    YSVB_ASSERT_PLUS(*this, >, Zero())
                    YSVB_SHOW(Tauint::getBinaryDataString())
                    YSVB_ASSERT_PLUS(target, <, Zero())
                    return ((DIV_P_0(target.minus(),true)).minus());
                } else {
                    //std::cout << "both positives " << std::endl;
                    YSVB_ASSERT_PLUS(*this, >=, Zero())
                    YSVB_ASSERT_PLUS(target, >=, Zero())
                    return (DIV_P_0(target,true));
                }
            }
        }
    }

    Tauint operator %(const Tauint & target) const {
        //std::cout << "== Tauint operator /(const Tauint & target) const " << std::endl;
        if (target == Zero()) {
            std::cout << "Fatal Error: Division for 0" << std::endl;
            return Zero();
        } else {
            if (get_sign()) {
                if (target.get_sign()) {
                    YSVB_ASSERT_PLUS(*this, <, Zero())
                    YSVB_ASSERT_PLUS(target, <, Zero())
                    return ((minus()).
                            DIV_P_0(target.
                            minus(),false)
                            );
                } else {
                    YSVB_ASSERT_PLUS(*this, <, Zero())
                    YSVB_ASSERT_PLUS(target, >, Zero())
                    return (((minus()).DIV_P_0(target,false)).minus());
                }
            } else {
                if (target.get_sign()) {
                    YSVB_ASSERT_PLUS(*this, >, Zero())
                    YSVB_ASSERT_PLUS(target, <, Zero())
                    return ((DIV_P_0(target.minus(),false)).minus());
                } else {
                    //std::cout << "== Tauint operator *(const Tauint & target) const " << std::endl;
                    YSVB_ASSERT_PLUS(*this, >=, Zero())
                    YSVB_ASSERT_PLUS(target, >=, Zero())
                    return (DIV_P_0(target,false));
                }
            }
        }
    }

#include "tau_test.h"
//    static void test() {
//        //using namespace Tauint<T,size>;
//        using namespace std;
//        std::cout << "== Tauint::test()" << std::endl;
//        Tauint myTauInt;
//
//        YSVB_SHOW("Inner Atributes:")
//        YSVB_ASSERT_TEST(myTauInt.getSize(), ==, size);
//        YSVB_ASSERT_TEST(myTauInt.getType(), ==, typeid (T).name());
//        std::string longBinaryNumber = "111111111111111111111111111110";
//        myTauInt.setBinaryDataFromString(longBinaryNumber.c_str());
//        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, longBinaryNumber)
//        longBinaryNumber = "100";
//        myTauInt.setBinaryDataFromString(longBinaryNumber.c_str());
//        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, longBinaryNumber)
//        //YSVB_SHOW(myTauInt.getBinaryDataString()) //11111111100000000000000000000000000000000
//
//            YSVB_SHOW("Test Sum:")
//            myTauInt = myTauInt + One();
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "101");
//            myTauInt = myTauInt + One();
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "110");
//            myTauInt = myTauInt + One();
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "111");
//            myTauInt = myTauInt + One();
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1000");
//    
//            YSVB_SHOW("Test Interface:")
//            myTauInt = binaryStringToTau("100000000000");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1000000000000");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "10000000000000");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "100000000000000");
//            myTauInt = myTauInt + myTauInt; //goes one here!!!
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1000000000000000");
//            myTauInt = myTauInt + myTauInt + unitToTau((T) 4);
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "10000000000000100");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "100000000000001000");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1000000000000010000");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "10000000000000100000");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "100000000000001000000");
//            myTauInt = binaryStringToTau("111111111111");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1111111111110");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "11111111111100");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "111111111111000");
//            myTauInt = myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1111111111110000");
//            myTauInt = myTauInt + unitToTau((T) 16);
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "10000000000000000");
//            myTauInt = myTauInt + unitToTau((T) 16);
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "10000000000010000");
//    
//            YSVB_SHOW("Subtraction:")
//            myTauInt = binaryStringToTau("10000000000010000");
//            myTauInt = myTauInt - binaryStringToTau("10000");
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "10000000000000000");
//            myTauInt = myTauInt - unitToTau((T) 16); //11111111111111111
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1111111111110000");
//            myTauInt = myTauInt - binaryStringToTau("1111111111110000");
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
//            myTauInt = myTauInt + myTauInt + unitToTau((T) 4);
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "100");
//            myTauInt = myTauInt - myTauInt - myTauInt + myTauInt;
//            YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
//    
//            YSVB_SHOW("Comparation:")
//            YSVB_ASSERT_TEST(bin, ==, 2)
//            myTauInt = binaryStringToTau("0");
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("1"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("10"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("11"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("100"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("111000"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("11111111111000111"))
//            YSVB_ASSERT_TEST(myTauInt, >, binaryStringToTau("10").minus())
//            YSVB_ASSERT_TEST(myTauInt, >, binaryStringToTau("11").minus())
//            YSVB_ASSERT_TEST(myTauInt, >, binaryStringToTau("100").minus())
//            YSVB_ASSERT_TEST(myTauInt, >, binaryStringToTau("111000").minus())
//            YSVB_ASSERT_TEST(myTauInt, >, binaryStringToTau("11111111111000111").minus())
//            myTauInt = binaryStringToTau("1");
//            YSVB_ASSERT_TEST(myTauInt, >, binaryStringToTau("0"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("10"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("11"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("100"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("111000"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("11111111111000111"))
//            myTauInt = binaryStringToTau("100");
//            YSVB_ASSERT_TEST(myTauInt, >, binaryStringToTau("0"))
//            YSVB_ASSERT_TEST(myTauInt, >, binaryStringToTau("10"))
//            YSVB_ASSERT_TEST(myTauInt, >, binaryStringToTau("11"))
//            YSVB_ASSERT_TEST(myTauInt, ==, binaryStringToTau("100"))
//            YSVB_ASSERT_TEST(myTauInt, >=, binaryStringToTau("100"))
//            YSVB_ASSERT_TEST(myTauInt, <=, binaryStringToTau("100"))
//            YSVB_ASSERT_TEST(myTauInt, !=, binaryStringToTau("101"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("111000"))
//            YSVB_ASSERT_TEST(myTauInt, <, binaryStringToTau("11111111111000111"))
//    
//        YSVB_SHOW("Order:")
//        myTauInt = Zero();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, -1);
//        myTauInt = One();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 0);
//        myTauInt = myTauInt * Two();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 1);
//        myTauInt = myTauInt * Two();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 2);
//        myTauInt = myTauInt * Two();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 3);
//        myTauInt = myTauInt * Two();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 4);
//        myTauInt = myTauInt * Two();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 5);
//        myTauInt = myTauInt * Two();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 6);
//        myTauInt = myTauInt * Two();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 7);
//        myTauInt = myTauInt * Two();
//        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 8);
////        myTauInt = myTauInt * myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 16);
////        FUN_LOG(1,OK)
////        myTauInt = myTauInt * myTauInt;
////        FUN_LOG(1,OK)
////        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 32);
////        FUN_LOG(1,OK)
////        myTauInt = myTauInt * myTauInt;
////        FUN_LOG(1,OK)
////        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 64);
////        FUN_LOG(1,OK)
////        myTauInt = myTauInt + myTauInt;
////        FUN_LOG(1,OK)
////        YSVB_ASSERT_TEST(myTauInt.getOrder(), ==, 65);//bigger than an integer
////        FUN_LOG(1,OK)
//
//        YSVB_SHOW("Shifting:")
//        myTauInt = One();
//        myTauInt = myTauInt << 2;
//        YSVB_ASSERT_TEST(myTauInt,==,Two()+Two());
//        myTauInt = myTauInt << 1;
//        YSVB_ASSERT_TEST(myTauInt,==,myTauInt+myTauInt);
////        myTauInt = Zero();
////        myTauInt = myTauInt << 1;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"0");
////        myTauInt = binaryStringToTau("1");
////        myTauInt = myTauInt << 1;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"10");
////        myTauInt = myTauInt << 1;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"100");
////        myTauInt = binaryStringToTau("1111");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"1111");
////        myTauInt = binaryStringToTau("1010101");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"1010101");
////        myTauInt = myTauInt << 1;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"1000");
////        myTauInt = myTauInt << 2;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"1000");
////        myTauInt = myTauInt + unitToTau(16);
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"11000");
////        myTauInt = myTauInt << 11;
////        myTauInt = binaryStringToTau("1100000000000000");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"1100000000000000");
////        myTauInt = myTauInt << 1;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(),==,"11000000000000000");
//        //                                                   1000000000000000
//
//
////        YSVB_SHOW("Multiplication:")
////        myTauInt = binaryStringToTau("0");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
////        myTauInt = myTauInt * myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
////        YSVB_ASSERT_TEST(binaryStringToTau("1").getBinaryDataString(), ==, "1")
////        YSVB_ASSERT_TEST((binaryStringToTau("1")).getBinaryDataString(), ==, "1")
////        myTauInt = binaryStringToTau("1");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1");
////        myTauInt = myTauInt * myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1");
////        myTauInt = myTauInt.minus() * myTauInt.minus();
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1");
////        myTauInt = binaryStringToTau("10000");
////        myTauInt = myTauInt.minus() * myTauInt + binaryStringToTau("100000000");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
////
////        YSVB_SHOW("atoi:")
////        myTauInt.setDecimalDataFromString("2");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "10");
////        myTauInt = myTauInt * myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "100");
////        myTauInt.setDecimalDataFromString("3");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "11");
////        myTauInt = myTauInt + myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "110");
////        myTauInt.setDecimalDataFromString("15");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1111");
////        myTauInt = myTauInt + myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "11110");
////        myTauInt.setDecimalDataFromString("9999999");
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "100110001001011001111111");
////        myTauInt = myTauInt + myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1001100010010110011111110");
////
////        YSVB_SHOW("quocient:")
////        myTauInt.setBinaryDataFromString("1");
////        myTauInt = Zero()/myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
////        myTauInt.setBinaryDataFromString("1");
////        myTauInt = myTauInt/myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1");
////        myTauInt.setBinaryDataFromString("1");
////        myTauInt = myTauInt/(myTauInt+myTauInt);
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
////        myTauInt.setBinaryDataFromString("10");
////        myTauInt = myTauInt/myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1");
////        myTauInt.setBinaryDataFromString("100000111101");
////        myTauInt = myTauInt/(One()+One());
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "10000011110");
////        myTauInt.setBinaryDataFromString("100000111101");
////        myTauInt = myTauInt/(myTauInt+One());
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
////        myTauInt.setBinaryDataFromString("100000111101");
////        myTauInt = myTauInt/(myTauInt-One());
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1");
////
////        YSVB_SHOW("remainder:")
////        myTauInt.setBinaryDataFromString("1");
////        myTauInt = myTauInt%myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
////        myTauInt.setBinaryDataFromString("1");
////        myTauInt = myTauInt%(myTauInt+myTauInt);
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1");
////        myTauInt.setBinaryDataFromString("10");
////        myTauInt = myTauInt%myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "0");
////        myTauInt.setBinaryDataFromString("100000111101");
////        myTauInt = myTauInt%(One()+One());
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1");
////        myTauInt.setBinaryDataFromString("100000111101");
////        myTauInt = myTauInt%(myTauInt+One());
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "100000111101");
////        myTauInt.setBinaryDataFromString("100000111101");
////        myTauInt = myTauInt%(myTauInt-One());
////        YSVB_ASSERT_TEST(myTauInt.getBinaryDataString(), ==, "1");
////
////        YSVB_SHOW("itoa:")
////        myTauInt.setBinaryDataFromString("10");
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "2");
////        myTauInt = myTauInt * myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "4");
////        myTauInt.setBinaryDataFromString("11");
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "3");
////        myTauInt = myTauInt + myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "6");
////        myTauInt.setBinaryDataFromString("1111");
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "15");
////        myTauInt = myTauInt + myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "30");
////        myTauInt.setBinaryDataFromString("100110001001011001111111");
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "9999999");
////        myTauInt = myTauInt + myTauInt;
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "19999998");
////
////        YSVB_SHOW("Full Operations:")
////        Tauint ti_A, ti_B;
////        ti_A.setDecimalDataFromString("-12345");
////        ti_B.setDecimalDataFromString("12345");
////        YSVB_ASSERT_TEST(ti_A, !=, ti_B);
////        YSVB_ASSERT_TEST(ti_A, <, ti_B);
////        YSVB_ASSERT_TEST(ti_A, <=, ti_B);
////        YSVB_ASSERT_TEST(ti_B, >, ti_A);
////        YSVB_ASSERT_TEST(ti_B, >=, ti_A);
////        YSVB_ASSERT_TEST(ti_A, ==, ti_A);
////        YSVB_ASSERT_TEST(ti_B, >=, ti_B);
////        YSVB_ASSERT_TEST(ti_B, <=, ti_B);
////        myTauInt = ti_A+ti_B;
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "0");
////        myTauInt = ti_A-ti_B;
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "-24690");
////        myTauInt = ti_A*ti_B;
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "-152399025");
////        myTauInt = ti_A/ti_B;
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "-1");
////        myTauInt = ti_A%ti_B;
////        YSVB_ASSERT_TEST(myTauInt.getDecimalString(), ==, "0");
//    }
};
